#pragma once

#include "ConditionalNode.h"

#include "Action.h"
#include "Clause.h"
#include "OutputPin.h"

namespace uml {

const bool ConditionalNode::isAssured_default_ = false;
const bool ConditionalNode::isDeterminate_default_ = false;
ConditionalNode::ConditionalNode(const QString& umlType)
    : StructuredActivityNode(umlType) {}

void ConditionalNode::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    StructuredActivityNode::fromJson(json, errorList);
    JsonSerializable::fromJsonArray(clauses_, "clauses", json, errorList);
    isAssured_ = json.value("isAssured").toBool(isAssured_default_);
    isDeterminate_ = json.value("isDeterminate").toBool(isDeterminate_default_);
    JsonSerializable::fromJsonArray(results_, "results", json, errorList);
}

void ConditionalNode::toJson(QJsonObject& json) {
    StructuredActivityNode::toJson(json);
    JsonSerializable::toJsonArray(clauses_, "clauses", json);
    if (isAssured_ != isAssured_default_) {
        json.insert("isAssured", isAssured_);
    }
    if (isDeterminate_ != isDeterminate_default_) {
        json.insert("isDeterminate", isDeterminate_);
    }
    JsonSerializable::toJsonArray(results_, "results", json);
}

/// <summary>
/// allActions
    /// Return only this ConditionalNode. This prevents Actions within the
    /// ConditionalNode from having their OutputPins used as bodyOutputs or decider Pins
    /// in containing LoopNodes or ConditionalNodes.
/// </summary>
    /// <code>
    /// result = (self->asSet())
    /// </code>
shared_ptr<vector<Action>> ConditionalNode::allActions() const
{
    return nullptr;
}

/// <summary>
/// clauses getter
/// The set of Clauses composing the ConditionalNode.
/// </summary>
vector<shared_ptr<Clause>>& ConditionalNode::clauses() {
    return clauses_;
}

/// <summary>
/// isAssured getter
/// If true, the modeler asserts that the test for at least one Clause of the
/// ConditionalNode will succeed.
/// </summary>
bool ConditionalNode::isAssured() const {
    return isAssured_;
}

/// <summary>
/// isAssured setter
/// If true, the modeler asserts that the test for at least one Clause of the
/// ConditionalNode will succeed.
/// </summary>
void ConditionalNode::setIsAssured(bool value) {
    isAssured_ = value;
}

/// <summary>
/// isDeterminate getter
/// If true, the modeler asserts that the test for at most one Clause of the
/// ConditionalNode will succeed.
/// </summary>
bool ConditionalNode::isDeterminate() const {
    return isDeterminate_;
}

/// <summary>
/// isDeterminate setter
/// If true, the modeler asserts that the test for at most one Clause of the
/// ConditionalNode will succeed.
/// </summary>
void ConditionalNode::setIsDeterminate(bool value) {
    isDeterminate_ = value;
}

/// <summary>
/// results getter
/// The OutputPins that onto which are moved values from the bodyOutputs of the
/// Clause selected for execution.
/// </summary>
vector<shared_ptr<OutputPin>>& ConditionalNode::results() {
    return results_;
}

} // namespace uml
